package service

import (
	log "github.com/sirupsen/logrus"
	"time"
	"usbipproxy/pb"
)

type OpFunc func(*MsgNotifyServiceImpl)

func WithChannelNum(channelNum int) OpFunc {
	return func(impl *MsgNotifyServiceImpl) {
		impl.channelNum = channelNum
	}
}

type MsgNotifyServiceImpl struct {
	outMsgChan chan *pb.ProxyMsg
	inMsgChan  chan *pb.ProxyMsg
	channelNum int
}

func (o *MsgNotifyServiceImpl) GetOutMsgChan() chan *pb.ProxyMsg {
	return o.outMsgChan
}

func (o *MsgNotifyServiceImpl) GetInMsgChan() chan *pb.ProxyMsg {
	return o.inMsgChan
}

func (o *MsgNotifyServiceImpl) SendMsgNoBlock(msg *pb.ProxyMsg) error {
	select {
	case o.outMsgChan <- msg:
		log.Debugf("MsgNotifyServiceImpl SendMsg msg type:%v \n", msg.GetMsgType())
	default:
		log.Infof("MsgNotifyServiceImpl send msg chan is full")
		time.Sleep(time.Millisecond * 1)
	}

	return nil
}

func (o *MsgNotifyServiceImpl) RecvMsgNoBlock(msg *pb.ProxyMsg) error {
	select {
	case o.inMsgChan <- msg:
		log.Debugf("MsgNotifyServiceImpl RecvMsg  msg: %+v \n", msg)
	default:
		log.Infof("MsgNotifyServiceImpl in msg chan is full")
	}

	return nil
}

func (o *MsgNotifyServiceImpl) SendMsg(msg *pb.ProxyMsg) error {
	select {
	case o.outMsgChan <- msg:
		return nil
	}
	return nil
}

func (o *MsgNotifyServiceImpl) RecvMsg(msg *pb.ProxyMsg) error {
	select {
	case o.inMsgChan <- msg:
		return nil
	}
	return nil
}

func NewMsgNotifyServiceImpl(withOpt ...OpFunc) MsgNotifyService {
	impl := &MsgNotifyServiceImpl{}
	for _, opt := range withOpt {
		opt(impl)
	}

	if impl.channelNum <= 0 {
		impl.channelNum = 60000
	}

	impl.outMsgChan = make(chan *pb.ProxyMsg, impl.channelNum)
	impl.inMsgChan = make(chan *pb.ProxyMsg, impl.channelNum)
	return impl
}
